package org.jackysoft.config;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.mock.web.MockServletContext;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.web.context.ServletContextAware;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.atomikos.jdbc.AtomikosDataSourceBean;

import freemarker.cache.TemplateLoader;
import freemarker.cache.WebappTemplateLoader;
import freemarker.template.ObjectWrapper;

@Configuration("commonConfiguration")
public class CommonConfiguration implements ServletContextAware,ResourceLoaderAware {
	protected final Log log = LogFactory.getLog(this.getClass());
	
	@Inject 
	private Environment env;

	private String rootPath;
	private String pdfPath;
	private String docPath;

	
	private File fileBase;
    private @Value("${rootUrl}") String rootUrl;
	private @Value("${pdfServer}")String pdfServer;
	private @Value("${pdfServerPort}")Integer pdfServerPort = 10086;
	private @Value("${diskBase}")String diskBase;
	private @Value("${imageDir}")String imageDir;	
	private ObjectWrapper freemarkerObjectWrapper;
	private TemplateLoader templateLoader;
	public static final String DOC = "doc";
	public static final String PDF = "pdf";
	public static final String DOCX = "docx";
	public static final String FMPATH = "fmtemps";

	public CommonConfiguration() {
	  
	}

	@PostConstruct
	public void initilize() {

		log.info("检查文件目录.....");
		if(servletContext==null)servletContext = new MockServletContext();
		System.setProperty("webappRoot", servletContext.getRealPath(""));
		fileBase = new File(diskBase+":"+File.separator,"files");
		log.info("检查文件存放根目录 : " + fileBase.getAbsolutePath());
		if (!fileBase.exists()) {
			log.info("目录不存在,现在创建目录");
			if (!fileBase.mkdir())
				throw new java.lang.IllegalArgumentException("不能创建目录"+diskBase);

		}
		
			
		log.info("检查文件目录完毕---------[ok]");
	}

	@PreDestroy
	public void destory() {

	}
	
	public String rootUrl(){
		return this.rootUrl;
	}

	public void checkUserDir(String name) {
		File dir = new File(fileBase, name);
		log.info(dir.getAbsolutePath());
		if (!dir.exists())
			if (!dir.mkdir())
				throw new java.lang.IllegalArgumentException("不能创建用户目录:"
						+ dir.getAbsolutePath());
		log.info(dir.getAbsolutePath()+" 已检查! ");
	}

	
	private ServletContext servletContext;
	private String freemarkerTemplateDirectory = "freemarker";

	public String getFreemarkerTemplateDirectory() {
		return this.freemarkerTemplateDirectory;
	}

	public void setServletContext(ServletContext servletContext) {

		this.servletContext = servletContext;
		this.freemarkerTemplateDirectory = this.servletContext.getRealPath("")
				+ File.separator + "freemarker" + File.separator;
	}

	// @Resource
	public void setFreemarkerObjectWrapper(ObjectWrapper freemarkerObjectWrapper) {
		this.freemarkerObjectWrapper = freemarkerObjectWrapper;
	}

	public ObjectWrapper getFreemarkerObjectWrapper() {
		return freemarkerObjectWrapper;
	}

	public @Bean
	ObjectWrapper freemarkerObjectWrapper() {
		this.freemarkerObjectWrapper = new freemarker.template.DefaultObjectWrapper();
		return this.freemarkerObjectWrapper;

	}

	// @Resource
	public void setTemplateLoader(TemplateLoader templateLoader) {
		this.templateLoader = templateLoader;
	}

	public TemplateLoader getTemplateLoader() {
		return templateLoader;
	}

	public @Bean
	TemplateLoader templateLoader() {
		this.templateLoader = new WebappTemplateLoader(this.servletContext,FMPATH);
		// new
			// freemarker.cache.ClassTemplateLoader(myfreemarker.MyTemplates.class,"");
		return this.templateLoader;
	}
	
	
	
	@Value("${xa.maxSize}")
	private int xaMaxSize= 300;
    @Value("${xa.minSize}")
	private int xaMinSize=50;
    @Value("${xa.driver}")
    private String xaDriver;
	@Bean(name="nmds",initMethod="init",destroyMethod="close")
	public DataSource nmds() throws IOException{
		String jdbcnm="jdbc-nm.properties";
		AtomikosDataSourceBean ds = new	AtomikosDataSourceBean();
		ds.setUniqueResourceName("mysql/normal");
		ds.setXaDataSourceClassName(xaDriver);		
		Resource xaprops = resourceResolver.getResource("classpath:"+jdbcnm);
		log.info(jdbcnm+" used at : "+xaprops.getFile().getAbsoluteFile());
		log.info(jdbcnm+" uri at :"+xaprops.getURI());
		Properties  hp = new Properties();
		hp.load(xaprops.getInputStream());
		ds.setXaProperties(hp);		
		ds.setMinPoolSize(xaMinSize);
		ds.setMaxPoolSize(xaMaxSize);		
	    ds.setTestQuery("select 1");
	    
		return ds;
	}
	
	
	  @Bean(name="idtds",initMethod="init",destroyMethod="close") 
	  public DataSource idtds() throws IOException{
		  String jdbcnm="jdbc-idt.properties";
			AtomikosDataSourceBean ds = new	AtomikosDataSourceBean();
			ds.setUniqueResourceName("mysql/identified");
			ds.setXaDataSourceClassName(xaDriver);
			Resource xaprops = resourceResolver.getResource("classpath:jdbc-idt.properties");
			log.info(jdbcnm+" used at : "+xaprops.getFile().getAbsoluteFile());
			log.info(jdbcnm+" uri at :"+xaprops.getURI());
			Properties  hp = new Properties();
			hp.load(xaprops.getInputStream());
			ds.setXaProperties(hp);
			ds.setMinPoolSize(xaMinSize);
			ds.setMaxPoolSize(xaMaxSize);		
		    ds.setTestQuery("select 1");		    
			return ds;
		
	  }
	  @Bean(initMethod="init",destroyMethod="close") 
	  public TransactionManager atomikosTransactionManager(){
		   UserTransactionManager utm = new UserTransactionManager();
		   utm.setForceShutdown(true);	 
		   return utm;
	  }
	  
	  @Bean 
	  public UserTransaction atomikosUserTransaction() throws SystemException{
		  UserTransactionImp utm = new UserTransactionImp();
		  utm.setTransactionTimeout(240);
		  
		  return utm;
	  }
	  
	  @Bean(name="transactionManager")
	  public JtaTransactionManager transactionManager() throws SystemException{
	      JtaTransactionManager dt = new JtaTransactionManager();
	      dt.setTransactionManager(atomikosTransactionManager());
	      dt.setUserTransaction(atomikosUserTransaction());
	      return dt;
	  }
    
    @Value("${mail.host}")
    private String mailHost;
    @Bean 
    public org.springframework.mail.javamail.JavaMailSender mailSender(){
    	org.springframework.mail.javamail.JavaMailSenderImpl jmail = 
    			new org.springframework.mail.javamail.JavaMailSenderImpl();
    	jmail.setHost(mailHost);
        return jmail;
    }
    
    
    
    //TODO Notics 生产环境解锁
    
    @Bean
	public org.springframework.web.filter.CharacterEncodingFilter characterEncodingFilter(){
		org.springframework.web.filter.CharacterEncodingFilter cef = 
				new org.springframework.web.filter.CharacterEncodingFilter();
		cef.setEncoding("UTF-8");
		cef.setForceEncoding(true);
		
		return cef;
	}
    
    
    
    
    
    @Bean 
    public SqlSessionFactoryBean  sqlSessionFactory() throws IOException{
    	
    	SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    	
    	Resource[] mapperLocations = new Resource[]{
    	   new ClassPathResource("org/jackysoft/mapper/ContractMapper.xml")
    	};
    	bean.setDataSource(nmds());    	  	
    	bean.setTypeAliasesPackage("org.jackysoft.entity");
    	bean.setMapperLocations(mapperLocations);
        log.info(bean);
        return bean;
    	
    }
    
    @Bean
    public org.mybatis.spring.SqlSessionTemplate sqlSession() throws Exception{
    	org.mybatis.spring.SqlSessionTemplate session = 
    			new org.mybatis.spring.SqlSessionTemplate(sqlSessionFactory().getObject());
    	
    	return session;
    }
  
   
   /* @Bean
    public MapperScannerConfigurer mapperScanner(){
    	MapperScannerConfigurer bean = new MapperScannerConfigurer();
    	bean.setBasePackage("org.jackysoft.mapper");
    	bean.setMarkerInterface(MarkerMapper.class);
    	bean.setSqlSessionTemplateBeanName("sqlSession");
    	return bean;
    }*/
    
    
    
	public void setPdfServerPort(Integer pdfServerPort) {
		this.pdfServerPort = pdfServerPort;
	}

	public Integer getPdfServerPort() {
		return pdfServerPort;
	}

	public void setPdfServer(String pdfServer) {
		this.pdfServer = pdfServer;
	}

	public String getPdfServer() {
		return pdfServer;
	}

	public String getDiskBase() {
		return diskBase;
	}

	public void setDiskBase(String diskBase) {
		this.diskBase = diskBase;
	}

	public String getImageDir() {
		return imageDir;
	}

	public void setImageDir(String imageDir) {
		this.imageDir = imageDir;
	}

	
	public String getRootPath() {
		return rootPath;
	}

	public String getPdfPath() {
		return pdfPath;
	}

	public void setPdfPath(String pdfPath) {
		this.pdfPath = pdfPath;
	}

	public String getDocPath() {
		return docPath;
	}

	public void setDocPath(String docPath) {
		this.docPath = docPath;
	}

	public void setRootPath(String rootPath) {
		this.rootPath = rootPath;
	}

	public String getContextUrl() {
		return System.getProperty("contextBase");
	}

	public String getUserFilebase(String name) {
		return fileBase.getAbsolutePath() + File.separatorChar + name + File.separator;
	}

	private static final String soaReginfo = "序列号：HDWN-KTYU-M8X8-B6GSI";
	private ResourcePatternResolver resourceResolver;
	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		resourceResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
		
	}
}
/**
 * 
 *
	
	@Bean(name="jotm")
	public JotmFactoryBean jotm(){
		JotmFactoryBean jotm = null;
		try {
			jotm = new JotmFactoryBean();
		} catch (NamingException e) {
			//logger.error(e);
			e.printStackTrace();
		}
		return jotm;
	}
	
	
	
	
	
	
		
	
    @Bean(name="snmds",destroyMethod="shutdown")
    public org.enhydra.jdbc.standard.StandardXADataSource
    snmds() {
    	
    	org.enhydra.jdbc.standard.StandardXADataSource 
    	sd = new org.enhydra.jdbc.standard.StandardXADataSource();
    	sd.setTransactionManager(jotm().getObject());
        sd.setUser(user);
        sd.setPassword(password);
    	try {
			sd.setDriverName(driverName);
		} catch (SQLException e) {
			//logger.error(e);
			e.printStackTrace();
		}
    	sd.setUrl(jdbcUrl);
		return sd;
    	
    }
    
    @Value("${xa.jdbcTestStmt}")
    private String xaJdbcTestStmt="select 1";
    @Value("${xa.maxSize}")
	private int xaMaxSize= 300;
    @Value("${xa.minSize}")
	private int xaMinSize=50;
    @Value("${xa.lifeTime}")
	private long xaLifeTime =300000;
    
    @Value("${xa.deadLockMaxWait}")
	private long xaDeadLockMaxWait = 3;
    @Value("${xa.deadLockRetryWait}")
	private long xaDeadLocRetryWait =50;
    @Value("${xa.sleepTime}")
	private long xaSleepTime=1000;
    @Value("${xa.checkLevelObject}")
	private int xaCheckLevelObject=4;
    
    @Bean(name="nmds",destroyMethod="shutdown")
	public 	org.enhydra.jdbc.pool.StandardXAPoolDataSource nmxads() throws Exception{
		org.enhydra.jdbc.pool.StandardXAPoolDataSource cds = new 
				org.enhydra.jdbc.pool.StandardXAPoolDataSource();		
		cds.setUser(user);
		cds.setPassword(password);
		cds.setDataSource(snmds());	


		cds.setLifeTime(xaLifeTime);
		cds.setJdbcTestStmt(xaJdbcTestStmt);
	    cds.setSleepTime(xaSleepTime);
		cds.setCheckLevelObject(xaCheckLevelObject);

		
		
		cds.setMaxSize(xaMaxSize);
		cds.setMinSize(xaMinSize);
		cds.setDeadLockMaxWait(xaDeadLockMaxWait);
		cds.setDeadLockRetryWait(xaDeadLocRetryWait);
		
		
		return cds;
	}
       
    
    @Value("${auth.jdbc.url}")
    private String authjdbcUrl;
	@Value("${auth.jdbc.username}")
    private String authuser;
	@Value("${auth.jdbc.password}")
    private String authpassword;
    @Bean(name="authds",destroyMethod="shutdown")
    public 	org.enhydra.jdbc.standard.StandardXADataSource authds(){
    	    	   	
    	org.enhydra.jdbc.standard.StandardXADataSource 
    	sd = new org.enhydra.jdbc.standard.StandardXADataSource();
    	sd.setTransactionManager(jotm().getObject());
    	try {
			sd.setDriverName(driverName);
		} catch (SQLException e) {
			//logger.error(e);
			e.printStackTrace();
		}
    	sd.setUser(authuser);
    	sd.setPassword(authpassword);
    	sd.setUrl(authjdbcUrl);
    
		return sd;  	
    	
    }

    @Bean(name="idtds",destroyMethod="shutdown") 
    public org.enhydra.jdbc.pool.StandardXAPoolDataSource idtds() throws Exception{
    	org.enhydra.jdbc.pool.StandardXAPoolDataSource cds = new 
				org.enhydra.jdbc.pool.StandardXAPoolDataSource();		
		cds.setUser(authuser);
		cds.setPassword(authpassword);
		cds.setDataSource(authds());
		
		cds.setLifeTime(xaLifeTime);
		cds.setJdbcTestStmt(xaJdbcTestStmt);
	    cds.setSleepTime(xaSleepTime);
		cds.setCheckLevelObject(xaCheckLevelObject);
	    
		cds.setMaxSize(xaMaxSize);
		cds.setMinSize(xaMinSize);
		cds.setDeadLockMaxWait(xaDeadLockMaxWait);
		cds.setDeadLockRetryWait(xaDeadLocRetryWait);
		return cds;
    }    
 * 
 * 
 */
